home *** CD-ROM | disk | FTP | other *** search
- Path: chronicle.mti.sgi.com!austern
- From: clamage@Eng.Sun.COM (Steve Clamage)
- Newsgroups: comp.std.c++
- Subject: Re: Correctness of compilers behavior
- Date: 20 Feb 1996 13:42:34 PST
- Organization: Sun Microsystems Inc.
- Approved: austern@isolde.mti.sgi.com
- Message-ID: <4gdc37$cqv@engnews1.Eng.Sun.COM>
- References: <199602180416.UAA01735@kronstadt.rahul.net>
- Reply-To: clamage@Eng.Sun.COM
- NNTP-Posting-Host: isolde.mti.sgi.com
- X-Original-Date: 20 Feb 1996 20:48:39 GMT
- X-Auth: PGPMoose V1.1 PGP comp.std.c++
- iQBVAwUBMSpAYky4NqrwXLNJAQEWQAH/RkJZoKQGhF+SNUkGeSgA5GsjcvE7eemd
- DndF/IF8DUsEzYY/bOY4hnCNw7kf4JAoLDpk5bPMujB4razPHQPP4w==
- =Rh5f
- Originator: austern@isolde.mti.sgi.com
-
- In article UAA01735@kronstadt.rahul.net, Ian T Zimmerman <itz@rahul.net> writes:
- >In article <4g3i93$9lp@mulga.cs.mu.OZ.AU> fjh@munta.cs.mu.OZ.AU
- >(Fergus Henderson) writes:
- >
- >> > for (unsigned i=0; i<size; ++i) {
- >> > (bptr+i)->~B();
- >> > new(aptr+i) A;
- >> > }
- >> >
- >
- >> >int main(void)
- >> >{
- >> > A* arr=foo(2);
- >> > delete [] arr;
- >>
- >> This has undefined behaviour. It contravenes 5.3.5[expr.delete]/2, which
- >> says that the expression passed to `delete []' must be a pointer to the
- >> first element of an array of objects allocated with `new []'; this is not
- >> the case, because although there once was such an array at that memory
- >> location, its lifetime ended when the memory was overwritten by the calls
- >> to placement new (see 3.8[basic.life]/1).
- >
- >Is it relevant here that A and B are unrelated classes?
-
- No. It only matters that A and B are not the same type. If A were derived
- from B or vice-versa the code would still be wrong. Example:
- class A : public B { ... };
- B* p = new A[10]; // legal, but a bad idea
- delete[] p; // error that does not have to be diagnosed
-
- Such code is valid for single objects, but not for arrays. Although an A
- is-a B, an array of A is NOT an array of B. Ordinarily you don't want
- C-style arrays of objects, especially polymorphic objects. You probably
- want an array of pointers so that you get object instead of value semantics,
- or an array class of values to avoid the inconvenient properties of C-style
- arrays.
-
- >What about the following code?
- >
- >A a;
- >
- >A* as = new A [10];
- >
- >for (int i = 0; i < 10; ++i) {
- > new (&as[i]) A(a);
- >}
- >delete [] as;
-
- It is valid to construct an object on top of the storage previously
- used for another object of the same type, so this code is mostly OK.
- Notice that you don't destroy the objects that were constructed with
- the default constructor.
-
- In the general case you would want to destroy the original objects
- before building new objects in their storage locations. Related to
- this point, the compiler will construct the original objects from
- index 0 up to index 9, and will destroy them in the reverse order.
- If the objects have any inter-dependencies, you might need to
- mimic that behavior to ensure a valid program. So you might write:
-
- A* as = new A[10]; // construct as[0] through as[9] in that order
- for( int i=10; --i>=0; )
- as[i]->~A(); // destroy in reverse order
- for( int i=0; i<10; ++i )
- new (&as[i]) A(a); // contruct from as[0] through as[9]
- ...
- delete[] as; // destroys as[9] down to as[0]
-
- If all you want is an array of values, you don't have to go through the
- extra construction and destruction if the number of elements is known
- at compile time:
- A as[10] = { a, a, a, a, a, a, a, a, a, a };
- or perhaps
- A as[10] = { A(arg0), A(arg1), A(arg2), ... , A(arg9) };
- to get different values in different slots.
-
- ---
- Steve Clamage, stephen.clamage@eng.sun.com
- ---
- [ To submit articles: Try just posting with your newsreader. If that fails,
- use mailto:std-c++@ncar.ucar.edu
- FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html
- Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html
- Comments? mailto:std-c++-request@ncar.ucar.edu
- ]
-